package stud.mpgame.network;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import stud.mpgame.network.util.ResponseMessageDescription;
import stud.mpgame.network.util.ResponseUserObject;

/**
 * @author f.pavel91@gmail.com
 * @version 1.4
 */
class TCPNetworkHandler extends IoHandlerAdapter {

    private final static Logger LOGGER = LoggerFactory.getLogger(TCPNetworkHandler.class);

    private NetworkMonitor networkMonitor;

    public TCPNetworkHandler(TCPNetworkMonitor networkMonitor) {
        this.networkMonitor = networkMonitor;
    }

    @Override
    public void messageReceived(IoSession session, Object object) throws Exception {
        super.messageReceived(session, object);
        Message message = (Message) object;
        MessageDescription messageDescription = message.getMessageDescription();

        if(messageDescription.isAutoResponseFlag()) {
            Message responseMessage = new Message(session, ResponseMessageDescription.getInstance());
            ResponseUserObject responseUserObject = new ResponseUserObject(message);
            responseMessage.putUserObject(responseUserObject);
            responseMessage.send();
        }

        ((MessageDispatcher) networkMonitor.getMessageDispatcher()).notifyMessageReceived(message);
        if(messageDescription.equals(ResponseMessageDescription.getInstance()))
            ((MessageDispatcher) networkMonitor.getResponseMessageDispatcher()).notifyMessageReceived(message);

    }

    @Override
    public void messageSent(IoSession session, Object object) throws Exception {
        Message message = (Message) object;
        ((MessageDispatcher) networkMonitor.getMessageDispatcher()).notifyMessageSent(message);
        if(message.getMessageDescription().equals(ResponseMessageDescription.getInstance()))
            ((MessageDispatcher) networkMonitor.getResponseMessageDispatcher()).notifyMessageSent(message);
        super.messageSent(session, object);
    }

    @Override
    public void sessionOpened(IoSession session) throws Exception {
        super.sessionOpened(session);
        networkMonitor.notifySessionOpened(session);
    }

    @Override
    public void sessionClosed(IoSession session) throws Exception {
        networkMonitor.notifySessionClosed(session);
        super.sessionClosed(session);
    }

    @Override
    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
        LOGGER.warn("Unexpected exception.", cause);
        // Close connection when unexpected exception is caught.
        session.close(true);
    }

}